<?php

class Kd_Html_Form_Select extends Kd_Html_Form_Element {

    private $_size = 1;
    private $_multiple = FALSE;
    private $_options = array();

    public function __construct() {
        parent::__construct();
        $this->templateName = 'form/select';
        $this->addClass('input', 'select');
    }

    public function getSize() {
        return $this->_size;
    }

    public function setSize($value) {
        $this->_size = $value;
        return $this;
    }

    public function getMultiple() {
        return $this->_multiple;
    }

    public function setMultiple($value) {
        $this->_multiple = $value;
        return $this;
    }

    public function clearOptions() {
        $this->_options = array();
        return $this;
    }

    public function &getOptions() {
        return $this->_options;
    }

    public function setOption($label, $value, $disabled = FALSE, $attributes = array()) {
        $this->_options[] = array(
            'label' => $label,
            'value' => $value,
            'disabled' => $disabled,
            'attributes' => $attributes
        );
        return $this;
    }

    public function addOption(array $values) {
        foreach ($values as $key => $value) {
            $this->setOption($value, $key);
        }
        return $this;
    }

    public function bindData($data, $labelKey = NULL, $valueKey = NULL) {
        if (!is_null($labelKey)) {
            $valueKey = is_null($valueKey) ? $labelKey : $valueKey;
            foreach ($data as $item) {
                $this->setOption($item[$labelKey], $item[$valueKey]);
            }
        } else {
            foreach ($data as $value => $label) {
                $this->setOption($label, $value);
            }
        }
        return $this;
    }

    protected function renderReadonly() {
        $this->setEnabled(FALSE)
                ->addClass('readonly');
        return $this->renderEditable();
    }

    protected function renderEditable() {

        if (!$this->getEnabled()) {
            $this->addClass('disabled');
        }

        $this->setAttribute('id', $this->getId())
                ->setAttribute('name', $this->getName());
        if ($this->getSize() > 1) {
            $this->setAttribute('size', $this->getSize());
        }
        if (!$this->getEnabled()) {
            $this->setAttribute('disabled', 'disabled');
        }
        if ($this->getMultiple()) {
            $this->setAttribute('multiple', 'multiple');
        }

        $selectedValues = is_array($this->getValue()) ? $this->getValue() : array($this->getValue());

        $result = '<select ' . $this->getAttributeHtml() . '>';
        foreach ($this->_options as $item) {
            $result .= $this->createOptionHtml($selectedValues, $item);
        }
        return $result . '</select>';
    }

    private function createOptionHtml($selectedValues, $option) {
        $selected = '';
        $disabled = '';
        $attribute = '';
        if (!empty($selectedValues)) {
            foreach ($selectedValues as $sv) {
                if (strlen($sv) == strlen($option['value']) && strcmp($sv, $option['value']) == 0) {
                    $selected = ' selected="selected"';
                }
            }
        }
        if (!empty($option['disabled'])) {
            $disabled = 'disabled="disabled"';
        }
        if (!empty($option['attributes']) && is_array($option['attributes'])) {
            $attribute = array();
            foreach ($option['attributes'] as $name => $value) {
                $attribute[] = $name . '="' . $value . '"';
            }
            $attribute = implode(' ', $attribute);
        }
        return sprintf('<option value="%s"%s%s%s>%s</option>', $option['value'], $selected, $disabled, $attribute, $option['label']);
    }

}